www.gusucode.com > VC 2D游戏编辑器-源码程序 > VC 2D游戏编辑器-源码程序/code/mapedit_source/Ddfunc.cpp

    //Download by http://www.NewXing.com
// Ddfunc.cpp: implementation of the CDdfunc class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MapEdit.h"
#include "Ddfunc.h"
#include "MapEditView.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern int		nSource;
extern int		nObj[3];
extern CString* cSourPath;
extern CString* cObjPath[3];
extern RECT		rShowPic;
extern int		izoom;
extern CView	*pView;
extern RECT		client;
extern bool		IsZoomDown;
extern CPoint	g_ptScrollPos;
extern bool		IsFirstShowSPic;
extern DWORD	dCurrentScreenX;
extern DWORD	dCurrentScreenY;

float sw, sh, fRealZoom;
RECT rLineRect;


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDdfunc::CDdfunc()
{
	lpDD = NULL;
	lpddsprimary = NULL;
	for(int i = 0; i < 4; i++)
		DDS[i] = NULL;
}

CDdfunc::~CDdfunc()
{
	for (int i=0;i<nSource;i++)
	{
		if(DDS[0][i])
		{
			DDS[0][i]->Release();
			DDS[0][i] = NULL;
		}
	}

	for(int j = 0; j < 3; j++)
	{
		for (i=0;i<nObj[j];i++)
		{
			if(DDS[0][i])
			{
				DDS[j+1][i]->Release();
				DDS[j+1][i] = NULL;
			}
		}
	}

	if(lpddsprimary)
	{
		lpddsprimary->Release();
		lpddsprimary = NULL;
	}

	if (lpDD)
	{
		lpDD->Release();
		lpDD = NULL;
	}

// return success or failure or your own return code here
}

bool CDdfunc::InitDirectDraw(HWND main_hwnd)
{
	hwnd = main_hwnd;
	DDSURFACEDESC2 ddsd;
	ghRet=DirectDrawCreateEx(NULL,(void**)&lpDD,IID_IDirectDraw7,NULL);
    DD_ASSERT(ghRet,"CreateDirectDraw");

    ghRet=lpDD->SetCooperativeLevel(hwnd,DDSCL_NORMAL);
	DD_ASSERT(ghRet,"Set Cooperative Level");

	DD_INIT(ddsd);
	ddsd.dwSize = sizeof( ddsd );

	ddsd.dwFlags = DDSD_CAPS;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

    ghRet = lpDD->CreateSurface( &ddsd, &lpddsprimary, NULL );
		
    DD_ASSERT(ghRet,"Create Primary");

	ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
	ddsd.dwHeight=rShowPic.bottom-rShowPic.top;//高
	ddsd.dwWidth= rShowPic.right-rShowPic.left;//宽

	ghRet = lpDD->CreateSurface( &ddsd, &lpddSmallPic, NULL );
		
    DD_ASSERT(ghRet,"Create SmallPic");

	ddsd.dwHeight=64*32;//高
	ddsd.dwWidth= 64*32;//宽

	ghRet = lpDD->CreateSurface( &ddsd, &lpddPicCell, NULL );
		
    DD_ASSERT(ghRet,"Create PicCell");

	ddsd.dwHeight=3*32;//高
	ddsd.dwWidth= 3*32;//宽

	ghRet = lpDD->CreateSurface( &ddsd, &lpddAlpha[0], NULL );
		
    DD_ASSERT(ghRet,"Create PicCell");


	int i, j;
	char result[MAX_PATH];
	char result1[MAX_PATH];
	GetCurrentDirectory(MAX_PATH,result1);
	strcat(result1,"\\resource\\");

	DDS[0] = new LPDIRECTDRAWSURFACE7[nSource];
	for (i=0;i<nSource;i++)
	{
		strcpy(result, result1);
		strcat(result,cSourPath[i]);
		DDS[0][i]=DDLoadBitmap(lpDD, result, 0, 0);	
		DDSetColorKey(DDS[0][i],RGB(0,0,0));
	}
	for(j = 0; j < 3; j++)
	{
		DDS[j+1] = new LPDIRECTDRAWSURFACE7[nObj[j]];
		for (i=0;i<nObj[j];i++)
		{
			strcpy(result, result1);
			strcat(result,cObjPath[j][i]);
			DDS[j+1][i]=DDLoadBitmap(lpDD, result, 0, 0);	
			DDSetColorKey(DDS[j+1][i],RGB(0,0,0));
		}
	}
	strcpy(result, result1);
	strcat(result, "alpha\\");
	strcat(result,"Sour_alpha.bmp");
	lpddAlpha[1] = DDLoadBitmap(lpDD, result, 0, 0);
	strcpy(result, result1);
	strcat(result, "alpha\\");
	strcat(result,"Dec_alpha.bmp");
	lpddAlpha[2] = DDLoadBitmap(lpDD, result, 0, 0);
	GetSurfaceData( );
	return true;
}


bool CDdfunc::InitFail(char*msg)
{
	MsgBox(msg);
    DestroyWindow(hwnd);
    return false;
}

void CDdfunc::GetSurfaceData( )
{
	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize=sizeof(ddsd);

	SW[0] = new long[nSource];
	SH[0] = new long[nSource];
	SP[0] = new long[nSource];
	pS[0] = (DWORD**)new DWORD[nSource];
	int i, j;
	for (i=0;i<nSource;i++)
	{
		DDS[0][i]->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL);
		SP[0][i] = ddsd.lPitch;
		pS[0][i] = (DWORD *)ddsd.lpSurface;
		SW[0][i] = ddsd.dwWidth;
		SH[0][i] = ddsd.dwHeight;
		DDS[0][i]->Unlock(NULL);
	}
	for(j = 0; j < 3; j++)
	{
		SW[j+1] = new long[nObj[j]];
		SH[j+1] = new long[nObj[j]];
		SP[j+1] = new long[nObj[j]];
		pS[j+1] = (DWORD**)new DWORD[nObj[j]];
		for (i=0;i<nObj[j];i++)
		{
			DDS[j+1][i]->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL);	
			SP[j+1][i] = ddsd.lPitch;
			pS[j+1][i] = (DWORD *)ddsd.lpSurface;
			SW[j+1][i] = ddsd.dwWidth;
			SH[j+1][i] = ddsd.dwHeight;
			DDS[j+1][i]->Unlock(NULL);
		}
	}
}

void CDdfunc::DrawlpddSmallPic( )
{
	lCenterW = (rShowPic.right-rShowPic.left)/2;
	lCenterH = (rShowPic.bottom-rShowPic.top)/2;

	if(sw > sh)
	{
		fRealZoom = sw / izoom;
		if(fRealZoom > sh)
		{
			drect.left = rShowPic.left;
			drect.right = rShowPic.right;
			drect.top = lCenterH-(int)(GameMap.pHeader.nHeight*32/fRealZoom)/2;
			drect.bottom = drect.top+(int)(GameMap.pHeader.nHeight*32/fRealZoom);
			srect.top = 0;
			srect.bottom = GameMap.pHeader.nHeight*32;

			if(IsZoomDown)
			{
				rLineRect.top = (long)(g_ptScrollPos.y/fRealZoom)+drect.top;
				rLineRect.bottom = rLineRect.top + (long)((client.bottom-client.top)/fRealZoom);
				SetSPicW( );
			}
			else
			{
				rLineRect.left = (long)((g_ptScrollPos.x-srect.left)/fRealZoom)+drect.left;
				rLineRect.right = rLineRect.left + (long)((client.right-client.left)/fRealZoom);
				rLineRect.top = (long)((g_ptScrollPos.y-srect.top)/fRealZoom)+drect.top;
				rLineRect.bottom = rLineRect.top + (long)((client.bottom-client.top)/fRealZoom);
			}
		}
		else
		{
			drect.left = rShowPic.left;
			drect.right = rShowPic.right;
			drect.top = rShowPic.top;
			drect.bottom = rShowPic.bottom;
			if(IsZoomDown)
			{
				SetSPicW( );
				SetSPicH( );
			}
			else
			{
				rLineRect.left = (long)((g_ptScrollPos.x-srect.left)/fRealZoom)+drect.left;
				rLineRect.right = rLineRect.left + (long)((client.right-client.left)/fRealZoom);
				rLineRect.top = (long)((g_ptScrollPos.y-srect.top)/fRealZoom)+drect.top;
				rLineRect.bottom = rLineRect.top + (long)((client.bottom-client.top)/fRealZoom);
			}
		}
	}
	else
	{
 		fRealZoom = sh / izoom;
		if(fRealZoom > sw)
		{
			drect.left = lCenterW - (int)(GameMap.pHeader.nWidth*32/fRealZoom)/2;
			drect.right = drect.left+(int)(GameMap.pHeader.nWidth*32/fRealZoom);
			drect.top = rShowPic.top;
			drect.bottom = rShowPic.bottom;
			srect.left = 0;
			srect.right = GameMap.pHeader.nWidth*32;
			if(IsZoomDown)
			{
				rLineRect.left = (long)((g_ptScrollPos.x-srect.left)/fRealZoom)+drect.left;
				rLineRect.right = rLineRect.left+(long)((client.right-client.left)/fRealZoom);
				SetSPicH( );
			}
			else
			{
				rLineRect.left = (long)((g_ptScrollPos.x-srect.left)/fRealZoom)+drect.left;
				rLineRect.right = rLineRect.left + (long)((client.right-client.left)/fRealZoom);
				rLineRect.top = (long)((g_ptScrollPos.y-srect.top)/fRealZoom)+drect.top;
				rLineRect.bottom = rLineRect.top + (long)((client.bottom-client.top)/fRealZoom);
			}
		}
		else
		{
			drect.left = rShowPic.left;
			drect.right = rShowPic.right;
			drect.top = rShowPic.top;
			drect.bottom = rShowPic.bottom;
			if(IsZoomDown)
			{
				SetSPicW( );
				SetSPicH( );
			}
			else
			{
				rLineRect.left = (long)((g_ptScrollPos.x-srect.left)/fRealZoom)+drect.left;
				rLineRect.right = rLineRect.left + (long)((client.right-client.left)/fRealZoom);
				rLineRect.top = (long)((g_ptScrollPos.y-srect.top)/fRealZoom)+drect.top;
				rLineRect.bottom = rLineRect.top + (long)((client.bottom-client.top)/fRealZoom);
			}
		}		
	}
	int iNum64x, iNum64y, id, type;
	iNum64x = GameMap.pHeader.nWidth / 64;
	iNum64y = GameMap.pHeader.nHeight /64;
	
	if(((srect.right-srect.left)/(32*64)==0)&&((srect.bottom-srect.top)/(32*64)==0))
		IsFirstShowSPic = false;
	if((iNum64x < 2)&&(iNum64y < 2))
	{
		DDBLTFX ddBltFx;
		ddBltFx.dwSize=sizeof(DDBLTFX);
		ddBltFx.dwFillColor=0;
		lpddSmallPic->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);

		lpddSmallPic->Blt(&drect, lpddData, &srect, DDBLT_WAIT, NULL);
	}
	else if((IsFirstShowSPic))
	{
		IsFirstShowSPic = false;

		int iX64, iY64, iCellX, iCellY;

		DDBLTFX ddBltFx;
		ddBltFx.dwSize=sizeof(DDBLTFX);
		ddBltFx.dwFillColor=0;
		lpddSmallPic->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
		int iMaxX = GameMap.pHeader.nWidth > 64? 64:GameMap.pHeader.nWidth;
		int iMaxY = GameMap.pHeader.nHeight > 64? 64:GameMap.pHeader.nHeight;
		for(iY64 = srect.top/(32*64); iY64 < (srect.bottom+32*64-1)/(32*64); iY64++)
			for(iX64 = srect.left/(32*64); iX64 < (srect.right+32*64-1)/(32*64); iX64++)
			{
				for(iCellY = 0; iCellY < iMaxY; iCellY ++)
					for(iCellX = 0; iCellX < iMaxX; iCellX ++)
					{
						id = GameMap.pSurfaceData[(iY64*64+iCellY)*GameMap.pHeader.nWidth+(iX64*64+iCellX)].nID;
						lpddPicCell->BltFast(iCellX*32, iCellY*32, DDS[0][id], NULL, NoKey);
			
						id = GameMap.pObjData[(iY64*64+iCellY)*GameMap.pHeader.nWidth+(iX64*64+iCellX)].nID;
						if(id == 255)
							continue;
						type = GameMap.pObjData[(iY64*64+iCellY)*GameMap.pHeader.nWidth+(iX64*64+iCellX)].nType;
						if(type == 0)
							continue;
						lpddPicCell->BltFast(iCellX*32, iCellY*32, DDS[type][id], NULL, SrcKey);
					}
				RECT drect64, srect64;
				srect64.left = iX64*32*64 > srect.left?iX64*32*64:srect.left;
				srect64.right = (iX64+1)*32*64 > srect.right? srect.right:(iX64+1)*32*64;
				srect64.top = iY64*32*64 > srect.top?iY64*32*64:srect.top;
				srect64.bottom = (iY64+1)*32*64 > srect.bottom?srect.bottom:(iY64+1)*32*64;
	
				drect64.left = (long)(drect.left+(srect64.left-srect.left)/fRealZoom+0.5);
				drect64.right = (long)(drect.left+(srect64.right-srect.left)/fRealZoom+0.5);
				drect64.top = (long)(drect.top+(srect64.top-srect.top)/fRealZoom+0.5);
				drect64.bottom = (long)(drect.top+(srect64.bottom-srect.top)/fRealZoom+0.5);
	
				srect64.left -= iX64*32*64;
				srect64.right -= iX64*32*64;
				srect64.top -= iY64*32*64;
				srect64.bottom -= iY64*32*64;
				lpddSmallPic->Blt(&drect64, lpddPicCell, &srect64, DDBLT_WAIT, NULL);
			}
	}
	else
	{
		RECT drect64, srect64;
		srect64.left = (long)(dCurrentScreenX*(64-(client.right-client.left+31)/32)*32) > srect.left?dCurrentScreenX*(64-(client.right-client.left+31)/32)*32:srect.left;
		srect64.right = (long)(dCurrentScreenX*(64-(client.right-client.left+31)/32)*32+32*64) > srect.right? srect.right:dCurrentScreenX*(64-(client.right-client.left+31)/32)*32+32*64;
		srect64.top = (long)(dCurrentScreenY*(64-(client.bottom-client.top+31)/32)*32) > srect.top?dCurrentScreenY*(64-(client.bottom-client.top+31)/32)*32:srect.top;
		srect64.bottom = (long)(dCurrentScreenY*(64-(client.bottom-client.top+31)/32)*32+32*64) > srect.bottom?srect.bottom:dCurrentScreenY*(64-(client.bottom-client.top+31)/32)*32+32*64;
	
		drect64.left = (long)(drect.left+(srect64.left-srect.left)/fRealZoom+0.5);
		drect64.right = (long)(drect.left+(srect64.right-srect.left)/fRealZoom+0.5);
		drect64.top = (long)(drect.top+(srect64.top-srect.top)/fRealZoom+0.5);
		drect64.bottom = (long)(drect.top+(srect64.bottom-srect.top)/fRealZoom+0.5);
	
		srect64.left -= (long)(dCurrentScreenX*(64-(client.right-client.left+31)/32)*32);
		srect64.right -= (long)(dCurrentScreenX*(64-(client.right-client.left+31)/32)*32);
		srect64.top -= (long)(dCurrentScreenY*(64-(client.bottom-client.top+31)/32)*32);
		srect64.bottom -= (long)(dCurrentScreenY*(64-(client.bottom-client.top+31)/32)*32);
		lpddSmallPic->Blt(&drect64, lpddData, &srect64, DDBLT_WAIT, NULL);
	}

	HDC hdc;
	if (lpddSmallPic->GetDC(&hdc) == DD_OK)
	{ 
		HPEN hpen = (HPEN)SelectObject (hdc, CreatePen (PS_DOT, 1, RGB(255, 0, 255)));
		MoveToEx (hdc, rLineRect.left, rLineRect.top, NULL);
		LineTo (hdc, rLineRect.right, rLineRect.top);
		LineTo (hdc, rLineRect.right, rLineRect.bottom);
		LineTo (hdc, rLineRect.left, rLineRect.bottom);
		LineTo (hdc, rLineRect.left, rLineRect.top) ;
		DeleteObject (SelectObject (hdc, hpen)) ;
        lpddSmallPic->ReleaseDC(hdc);
	}
	IsZoomDown = false;
}
void CDdfunc::SetSPicW( )
{
	rLineRect.left = ((rShowPic.right-rShowPic.left)-(long)((client.right-client.left)/fRealZoom))/2;
	srect.left = g_ptScrollPos.x-(long)((rLineRect.left - rShowPic.left)*fRealZoom);
	if(srect.left < 0)
	{
		srect.left = 0;
		srect.right = GameMap.pHeader.nWidth*32 / izoom;
		rLineRect.left = (long)(g_ptScrollPos.x/fRealZoom)+rShowPic.left;
	}
	else
	{
		srect.right = srect.left + (long)((rShowPic.right-rShowPic.left)*fRealZoom);
		if(srect.right > (long)(GameMap.pHeader.nWidth*32))
		{
			srect.right = GameMap.pHeader.nWidth*32;
			srect.left = srect.right-(long)((rShowPic.right-rShowPic.left)*fRealZoom);
			rLineRect.left = rShowPic.right-(long)((srect.right-g_ptScrollPos.x)/fRealZoom);
		}
	}
	rLineRect.right = rLineRect.left+(long)((client.right-client.left)/fRealZoom);
}

void CDdfunc::SetSPicH( )
{
	rLineRect.top = ((rShowPic.bottom-rShowPic.top)-(long)((client.bottom-client.top)/fRealZoom))/2;
	srect.top = g_ptScrollPos.y-(long)((rLineRect.top-rShowPic.top)*fRealZoom);
	if(srect.top < 0)
	{
		srect.top = 0;
		srect.bottom = GameMap.pHeader.nHeight*32/izoom;
		rLineRect.top = (long)(g_ptScrollPos.y/fRealZoom)+rShowPic.top;
	}
	else
	{
		srect.bottom = srect.top+(long)((rShowPic.bottom-rShowPic.top)*fRealZoom);
		if(srect.bottom > (long)(GameMap.pHeader.nHeight*32))
		{
			srect.bottom = GameMap.pHeader.nHeight*32;
			srect.top = srect.bottom-(long)((rShowPic.bottom-rShowPic.top)*fRealZoom);
			rLineRect.top = rShowPic.bottom-(long)((srect.bottom-g_ptScrollPos.y)/fRealZoom);
		}
	}
	rLineRect.bottom = rLineRect.top+(long)((client.bottom-client.top)/fRealZoom);
}

RECT CDdfunc::GetSrect( )
{
	return srect;
}

RECT CDdfunc::GetDrect( )
{
	return drect;
}